package com.hzy.es.service;

import com.alibaba.fastjson.JSONObject;
import com.hzy.es.Item;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ExecutionException;

@Service
public class ESService {
    private String indexName = "goods";
    private String ikIndexName = "ik";
    private String typeName = "goods";

    @Autowired
    TransportClient client;

    /** 创建索引*/
    public void createIndex() throws ExecutionException, InterruptedException {
        IndicesAdminClient indices = client.admin().indices();
        CreateIndexResponse response= indices.prepareCreate(indexName).execute().get();
        System.out.println(response.isAcknowledged());
    }

    /** 删除索引*/
    public void deleteIndex(){
        AcknowledgedResponse deleteIndexResponse = client.admin().indices().prepareDelete(indexName).get();
        System.out.println(deleteIndexResponse.isAcknowledged());
    }

    /** 索引数据*/
    public void saveData(){
        JSONObject data = new JSONObject();
        data.put("name", "jack");
        data.put("type", "1");
        XContentType contentType = XContentType.JSON;
        // 不指定id es分配id
        IndexResponse indexResponse = client.prepareIndex(indexName, typeName).
                setSource(data, contentType).get();
        System.out.println(indexResponse.status().name());

        // 指定id
        indexResponse = client.prepareIndex(indexName, typeName, "2").
                setSource(data, contentType).get();
        System.out.println(indexResponse.status().name());
    }

    /** bulk操作，批量索引数据*/
    public void bulkSave() throws Exception {
        List<Item> cars = new ArrayList<>();
        BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
        for (Item car : cars) {
            Map map = Obj2Map(car);
            bulkRequestBuilder.add(client.prepareIndex(indexName, typeName, car.getId() + "").setSource(map));
        }
        BulkResponse bulkItemResponses = bulkRequestBuilder.get();
        System.out.println(bulkItemResponses.hasFailures());
    }

    public  Map<String,Object> Obj2Map(Object obj) throws Exception{
        Map<String,Object> map=new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for(Field field:fields){
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
        return map;
    }

    /** 删除索引数据*/
    public void delete(){
        DeleteResponse deleteResponse = client.prepareDelete(indexName, typeName, "2").get();
        System.out.println(deleteResponse.getResult().name());
    }

    public void get(){
        /** 返回指定字段*/
        String[] sourceFields = {"id","name","aPrice"};
        GetResponse documentFields = client.prepareGet(indexName, typeName, 22 + "").setStoredFields("_source").setFetchSource(sourceFields, null).get();
        Map<String, Object> source = documentFields.getSource();
        for (Map.Entry entry : source.entrySet()) {
            System.out.println(entry.getKey() + "  " + entry.getValue());
        }
    }

    /** 修改数据*/
    public void update() throws Exception {
        Item item = new Item();
        client.prepareUpdate(indexName,typeName,"24").setDoc(JSONObject.toJSONString(item), XContentType.JSON).get();

//		Map<String, Object> stringObjectMap = Obj2Map(goods);
//		client.prepareUpdate(indexName,typeName,"121").setDoc(stringObjectMap).get();
    }

    /** 有点类似multiMatch*/
    public void queryStringQueryBuilder(){
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("帕杰罗·劲畅").field("description")).setSize(10);
//		SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("ZJYLQ").field("pycode")).setSize(10);
//		SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("XZJYLQQ").field("pycode")).setSize(10);
        execSearch(builder);
    }

    private void execSearch(SearchRequestBuilder builder){
        SearchResponse response = builder.get();
        Iterator<SearchHit> iterator = response.getHits().iterator();
        while (iterator.hasNext()){
            SearchHit next = iterator.next();
            System.out.println(			next.getSourceAsMap());
        }
    }

    /** 单字段匹配*/
    public void matchQueryBuilder(){
//		QueryBuilder
//		MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("jfcode", "30049");
        /** 单字段查询*/
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("pycode", "XZJYLQQ");
//		MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("pycode", "JYLQQ");
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(matchQueryBuilder);
        execSearch(builder);
    }

    /** 多字段匹配*/
    public void multiMatchQueryBuilder(){
        /** 多字段对value查询*/
        MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder("滤清器", "name","typeName");
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(multiMatchQueryBuilder).setSize(10);
        execSearch(builder);
    }

    /** 范围查询， gt lt gte lte分别代表 > < >= <=*/
    public void rangeQueryBuilder(){
        // 12<=bPrice<=13
        RangeQueryBuilder queryBuilder = new RangeQueryBuilder("bPrice");
        queryBuilder.gte(12);
        queryBuilder.lte(13);
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10);
        execSearch(builder);
    }

    /** 根据id查询*/
    public void idsQuery(){
        IdsQueryBuilder queryBuilder = new IdsQueryBuilder().types(typeName).addIds("10","21","22");
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10);
        execSearch(builder);
    }

    /** 符合查询，， must必须满足、mustnot必须不满足、should可满足可不满足*/
    public void boolMatchQuery(){
        /** 多字段对value查询*/
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(new MatchQueryBuilder("marketPrice", "8"));
        queryBuilder.mustNot(new RangeQueryBuilder("bPrice").gte(12).lt(13));
        queryBuilder.should(new MatchQueryBuilder("marketPrice", "8"));
        /** marketPrice=8 并且 bPrice不在12、13之间*/
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10);
        execSearch(builder);
    }

    // ? * 分别代替一个字符、多个字符。
    public void wildCardMatchQuery(){
        /** 多字段对value查询*/
        WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("jfcode", "*36033");
//		WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("jfcode", "?36033");
//		WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("name", "*机油滤*");
        /** marketPrice=8 并且 bPrice不在12、13之间*/
        SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10);
        execSearch(builder);
    }
}
